package com.summer.halfSyncAsync;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executor;

/**
 * Half-sync/Half-async 模式可复用实现
 * @author Administrator
 * @param <V> 同步任务处理结果类型*/
public abstract class AsyncTask<V> {
	
	//相当于Half-sync/Half-async模式的同步层：用于执行异步层提交的任务。
	private volatile Executor executor;
	private final static ExecutorService DEFAULT_EXECUTOR;
	static{
		DEFAULT_EXECUTOR = new ThreadPoolExecutor(1,1,8,TimeUnit.HOURS,
				new LinkedBlockingDeque<Runnable>(),
				new ThreadFactory(){
					@Override
					public Thread newThread(Runnable r) {
						Thread thread = new Thread(r,"AsyncTaskDefaultWorker");
						//使该线程在JVM关闭时自动停止
						thread.setDaemon(true);
						return thread;
					}
				},
				new RejectedExecutionHandler() {
					/**
					 * 该RejectedExecutionHandler支持重试。
					 * 当任务被ThreadPoolExecutor拒绝时,
					 * 该RejectedExecutionHandler支持
					 * 重新将任务放入ThreadPoolExecutor的工作队列
					 * (这意味着,此时客户端代码需要等待ThreadPoolExecutor的队列非满).
					 * */
					@Override
					public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
						if(!executor.isShutdown()){
							try {
								executor.getQueue().put(r);
							} catch (InterruptedException e) {}
						}
					}
				}
		);
	}
	
	public AsyncTask(){
		this(DEFAULT_EXECUTOR);
	}
	
	public AsyncTask(Executor executor){
		this.executor = executor;
	}
	
	public void setExecutor(Executor executor){
		this.executor = executor;
	}
	
	/**
	 * 留给子类实现耗时较短的任务，默认实现什么也不做。
	 * @param params
	 *        客户端代码调用dispatch方法时所传递的参数列表
	 * */
	protected void onPreExecute(Object... params) {
		//什么也不做
	}
	
	/**
	 * 留给子类实现。用于实现同步任务执行结束后所需执行的操作。默认实现什么也不做。
	 * @param result 同步任务处理结果
	 * */
	protected void onPostExecute(V result) {
		//什么也不做
	}
	
	protected void onExecutionError(Exception exception) {
		exception.printStackTrace();
	}
	
	/**
	 * 留给子线程实现耗时较长的任务(同步任务)，由后台线程负责调用。
	 * @param params 客户端代码调用dispatch方法时所传递的参数列表
	 * @return 同步任务处理结果*/
	protected abstract V doInBackground(Object... params);
	
	/**
	 * 对外(其子类)暴露的服务方法。该类的子类需要定义一个比该方法命名更为具体的服务方法(如 downloadLargeFile).
	 * 该命名具体的服务方法(downloadLargeFile)可以直接调用该方法.
	 * @param params 客户端代码传递的参数列表
	 * @return 可借以获取任务处理结果的Promise实例*/
	protected Future<V> dispatch(final Object... params) {
		FutureTask<V> ft = null;
		onPreExecute(params);
		Callable<V> callable = new Callable<V>(){
			@Override
			public V call() throws Exception {
				V result;
				result = doInBackground(params);
				return result;
			}
		};
		ft = new FutureTask<V>(callable){
			@Override
			protected void done() {
				try {
					onPostExecute(this.get());
				} catch (InterruptedException exception) {
					onExecutionError(exception);
				} catch (ExecutionException exception) {
					onExecutionError(exception);
				}
			}
			
		};
		
		executor.execute(ft);
		return ft;
	}
}
